/*
 * Project CHEN Rendering Engine : /area.hpp
 * Created: 2020-12-16, Last modified:  2021-01-27
 * 
 * Declarations of multiple area lights.
 * 
 * Copyright (C) 2021 Hineven (hineven@pku.edu.cn)
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef _H_LIGHT_AREA
#define _H_LIGHT_AREA
#include "../core/heads.hpp"
#include "../core/flags.hpp"
#include "../core/light.hpp"
#include "../core/interaction.hpp"
namespace chen {


// Diffuse area light.
// Have NO support for shading normals.
class DiffuseAreaLight: public AreaLight {
public:
    using AreaLight::AreaLight; // 继承构造函数
    // Sample a light ray from the light source illuminating
    // the surface interaction si
    Spectrum sampleLi (
        const Interact & si, const Point2 & u,
        Vector3 * wi, Float * pdf, bool * occ
    ) const ;
    inline Spectrum Lo(
        const Interact & in, const Vector3 & wo, const Point2 & uv
    ) const {
        unused(uv);
        if(in.hit != this->shape || !(flipped^in.ng.sideWith(wo))) return 0;
        return identity;
    }
    // Generate a power-normalized photon, it has to be
    // power-normalized to present physically correct visual effect
    Spectrum sampleLo (
        const Point2 & up, const Point2 & ud,
        Ray * r, Float * pdf, Float * cosv
    ) const ;
    // Total area of the area light
    inline Float area () const {
        return shape->area();
    }
    // Total power of the area light
    inline Float power () const {
        return shape->area()*identity_energy;
    }
    inline Spectrum LeFrom (const Ray & r) const {
        return 0;
    }
};




}
#endif // __AREA_H__